package org.example.school.business;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.example.school.common.Context;
import org.example.school.entity.AttendanceRecords;
import org.example.school.entity.Classes;
import org.example.school.entity.Leave;
import org.example.school.entity.Students;
import org.example.school.entity.Teachers;
import org.example.school.model.dto.AttendanceRecordsVo;
import org.example.school.model.dto.TeachingClassDTO;
import org.example.school.model.dto.leaveBySelectDTO;
import org.example.school.service.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

@Component
public class TeacherInfo {
    
    @Autowired
    private ILeaveService leaveService;
    
    @Autowired
    private IAttendanceRecordsService attendanceRecordsService;
    
    @Autowired
    private IStudentsService studentsService;
    
    @Autowired
    private IClassesService classesService;
    
    @Autowired
    private ITeachersService teachersService;
    
    /**
     * 根据条件查询学生请假信息
     * @param leaveBySelectDTO 查询条件
     * @return 请假列表
     */
    public List<Leave> getLeaveStudents(leaveBySelectDTO leaveBySelectDTO) {
        return leaveService.lambdaQuery()
                .eq(Leave::getTeacherId, Context.getId())
                .eq(leaveBySelectDTO.getStudentNumber() != null, Leave::getStudentNumber, leaveBySelectDTO.getStudentNumber())
                .eq(leaveBySelectDTO.getStartDate() != null, Leave::getStartDate, leaveBySelectDTO.getStartDate())
                .eq(leaveBySelectDTO.getEndDate() != null, Leave::getEndDate, leaveBySelectDTO.getEndDate())
                .eq(leaveBySelectDTO.getStatus() != null, Leave::getStatus, leaveBySelectDTO.getStatus())
                .like(leaveBySelectDTO.getStudentName() != null, Leave::getStudentName, leaveBySelectDTO.getStudentName())
                .list();
    }
    
    /**
     * 审批学生请假申请
     * @param leaveId 请假ID
     * @param status 状态
     * @return 审批结果
     */
    public String updateLeave(String leaveId, String status) {
        Leave leave = leaveService.getById(leaveId);
        leave.setStatus(status);
        boolean update = leaveService.updateById(leave);
        if (update) {
            return "修改成功";
        } else {
            throw new RuntimeException("修改失败");
        }
    }
    
    /**
     * 查询当天未打卡学生
     * @param date 日期，不传则为当天
     * @return 未打卡学生列表
     */
    public List<AttendanceRecordsVo> getAbsentStudents(LocalDate date) {
        try {
            LocalDate targetDate = date != null ? date : LocalDate.now();
            Long teacherId = Context.getId();
            // 获取该教师作为班主任的班级
            List<Classes> headTeacherClasses = classesService.lambdaQuery().eq(Classes::getHeadTeacherId, teacherId).list();
            if (headTeacherClasses.isEmpty()) {
                return new ArrayList<>();
            }
            List<Students> students = new ArrayList<>();
            for (Classes clazz : headTeacherClasses){
                List<Students> studentsByClass = studentsService.lambdaQuery().eq(Students::getClassId, clazz.getId()).list();
                students.addAll(studentsByClass);
            }
            List<AttendanceRecordsVo> absentStudents = new ArrayList<>();
            
            // 检查是否为周末
            if (targetDate.getDayOfWeek().getValue() >= 6) { // 6=周六, 7=周日
                return absentStudents;
            }

            for (Students student : students) {
                // 检查该学生当天是否有考勤记录（排除请假状态）
                AttendanceRecords record = attendanceRecordsService.getOne(
                        new QueryWrapper<AttendanceRecords>()
                                .eq("student_id", student.getId())
                                .eq("record_date", targetDate)
                );

                if (record == null) {
                    absentStudents.add(new AttendanceRecordsVo(student.getStudentNumber(), student.getFullName(),student.getGender(),student.getClassId()));
                }
            }
            return absentStudents;
        } catch (Exception e) {
            throw new RuntimeException("查询失败: " + e.getMessage());
        }
    }
    
    /**
     * 获取教师授课班级
     * @return 授课班级列表
     */
    public List<TeachingClassDTO> getTeachingClasses() {
        // 获取当前教师信息
        Teachers teacher = teachersService.lambdaQuery()
                .eq(Teachers::getUserId, Context.getId())
                .one();
        
        if (teacher == null) {
            throw new RuntimeException("教师信息不存在");
        }
        
        // 获取该教师作为班主任的班级
        List<Classes> headTeacherClasses = classesService.lambdaQuery()
                .eq(Classes::getHeadTeacherId, teacher.getId())
                .list();
        
        // 转换为DTO
        return headTeacherClasses.stream().map(clazz -> {
            TeachingClassDTO dto = new TeachingClassDTO();
            dto.setId(Long.valueOf(clazz.getId()));
            dto.setClassName(clazz.getClassName());
            dto.setSubjectName("班主任"); // 班主任身份
            return dto;
        }).collect(Collectors.toList());
    }
    /**
     * 定时生成未打卡考勤记录
     * 每天晚上6点执行
     */
    /**
     * 定时生成未打卡考勤记录 - 优化版本
     * 每天晚上6点执行
     */
    public void autoGenerateAbsentRecords() {
        try {
            LocalDate today = LocalDate.now();

            // 检查是否为周末
            if (today.getDayOfWeek().getValue() >= 6) {
                return; // 周末不生成考勤记录
            }

            // 分批处理学生，每次处理100个
            int pageSize = 100;
            int currentPage = 0;
            List<Students> studentsBatch;

            do {
                // 分页获取学生列表
                studentsBatch = studentsService.page(
                        new Page<>(currentPage, pageSize)
                ).getRecords();

                if (!studentsBatch.isEmpty()) {
                    // 提取学生ID列表
                    List<Long> studentIds = studentsBatch.stream()
                            .map(Students::getId)
                            .collect(Collectors.toList());

                    // 批量查询这些学生当天的考勤记录
                    List<AttendanceRecords> existingRecords = attendanceRecordsService.list(
                            new QueryWrapper<AttendanceRecords>()
                                    .in("student_id", studentIds)
                                    .eq("record_date", today)
                    );

                    // 获取已有考勤记录的学生ID集合
                    Set<Long> recordedStudentIds = existingRecords.stream()
                            .map(AttendanceRecords::getStudentId)
                            .collect(Collectors.toSet());

                    // 筛选出没有考勤记录的学生
                    List<AttendanceRecords> absentRecordsToInsert = studentsBatch.stream()
                            .filter(student -> !recordedStudentIds.contains(student.getId()))
                            .map(student -> {
                                AttendanceRecords absentRecord = new AttendanceRecords();
                                absentRecord.setStudentId(student.getId());
                                absentRecord.setRecordDate(today);
                                absentRecord.setStatus("6");
                                absentRecord.setRemarks("未打卡");
                                absentRecord.setRecordedByTeacherId(99999L);
                                return absentRecord;
                            })
                            .collect(Collectors.toList());

                    // 批量插入缺勤记录
                    if (!absentRecordsToInsert.isEmpty()) {
                        attendanceRecordsService.saveBatch(absentRecordsToInsert);
                    }
                }

                currentPage++;
            } while (studentsBatch.size() == pageSize);

        } catch (Exception e) {
            throw new RuntimeException("自动生成未打卡记录失败: " + e.getMessage());
        }
    }



}